/**
 * Copyright (c) 2012 Sean Beecroft, Permission is hereby granted, free of
 * charge, to any person obtaining a copy of this software and associated
 * documentation files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use, copy, modify,
 * merge, publish, distribute, sublicense, and/or sell copies of the Software,
 * and to permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 * 
 * For more information on this project and others, please visit my google code 
 * repository:
 * https://code.google.com/u/seanbeecroft@gmail.com/
 */
package noname.webserver;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;

public class NonameWebserver extends Thread {

    static String applicationName = "Noname Server";
    OutputStream owr;
    static HashMap hm = new HashMap();
    static String[][] ext = new String[][]{
        {"jpg", "image/jpeg"}, {"gif", "image/gif"}, {"png", "image/png"}, {"ico", "image/ico"}, {"html", "text/html"}, {"xml", "text/xml"}, {"css", "text/css"}, {"txt", "text/plain"}, {"doc", "application/msword"}
    };
    int port = 0;

    static {
        for (int i = 0; i < ext.length; i++) {
            hm.put(ext[i][0], ext[i][1]);
        }
    }

    public void log(String line) {
        SimpleDateFormat df = new SimpleDateFormat("dd-MM-YYYY");
        try {
            PrintWriter log = new PrintWriter(new FileOutputStream(new File("./logs/log-" + df.format(new Date(System.currentTimeMillis())) + ".log"), true));
            log.println(line);
            System.out.println(line);
            log.close();
        } catch (Exception ex) {
        }
    }

    public void println() throws IOException {
        println("");
    }

    public void println(String content) throws IOException {
        content += "\n";
        byte[] ba = content.getBytes();
        owr.write(ba);
    }

    public NonameWebserver(int port) {
        this.port = port;
    }

    public void run() {
        while (true) {
            Socket sock = null;
            ServerSocket socket = null;
            try {
                Date d = new Date(System.currentTimeMillis());
                SimpleDateFormat fmt = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z");
                socket = new ServerSocket(port);
                sock = socket.accept();
                BufferedReader reader = new BufferedReader(new InputStreamReader(sock.getInputStream()));
                String str = reader.readLine();
                log(str);
                String[] arg = str.split(" ");
                arg[1] = arg[1].equals("/")?"/index.html":arg[1];
                String[] extl = arg[1].split("\\.");
                log("LOG:" + arg[1] + extl[1]);
                String ct = (String) hm.get(extl[1].toLowerCase());
                
                File file = new File("." + File.separator + "ROOT" + File.separator + arg[1]);
                long len = file.length();
                byte[] array = new byte[(int) len];
                FileInputStream fis = new FileInputStream(file);
                int rn = fis.read(array, 0, (int) len);
                owr = sock.getOutputStream();
                println("HTTP/1.1 200 OK");
                println("Date: " + fmt.format(d));
                println("Content-Type: " + ct);
                println("Content-Length:" + len);
                println();
                owr.write(array, 0, (int) len);
                owr.flush();
                owr.close();
                log("SENT -> " + file.getName() + " (" + rn + " bytes) TO " + sock.getInetAddress());
            } catch (Exception ex1) {
                log(ex1.getMessage());
                ex1.printStackTrace();
            } finally {
                try {
                    sock.close();
                    socket.close();
                } catch (Exception ex) {
                    log(ex.getMessage());
                    ex.printStackTrace();
                }
            }
        }
    }

    public static void main(String[] args) {
        try {
            System.out.println("Starting " + NonameWebserver.applicationName + "...");
            NonameWebserver m = new NonameWebserver(args.length == 0 ? 80 : Integer.parseInt(args[0]));
            m.start();
            System.out.println(NonameWebserver.applicationName + " Started.");
        } catch (Exception ex) {
            System.out.println("Usage:java -jar NonameWebserver.jar <port>");
            System.out.println("Example:java -jar NonameWebserver.jar 8080");
            System.exit(-1);
        }
    }
}
